package sg.edu.nus.iss.billing.gui;

import java.io.FileInputStream;
import java.util.*;
import java.util.List;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import sg.edu.nus.iss.billing.BillingApplication;
import sg.edu.nus.iss.billing.BillingConstants;
import sg.edu.nus.iss.billing.BillingConstants.SearchSortBy;
import sg.edu.nus.iss.billing.BillingConstants.SystemState;
import sg.edu.nus.iss.billing.controller.ComplaintController;
import sg.edu.nus.iss.billing.exceptions.ControllerException;
import sg.edu.nus.iss.billing.model.complaint.Complaint;
import sg.edu.nus.iss.billing.model.complaint.Complaint.ComplaintStatus;
import sg.edu.nus.iss.billing.model.complaint.ComplaintSorter;

/**
 * @author Yeo Hee Ling, Ananda, Saravana
 *
 */
public class SearchComplaintPanel extends JPanel implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	
	private Properties properties;
	private BillingApplication billingAppl;
	private List<Complaint> matchedComplaints;
	private JButton btnSearch, btnViewComplaint, btnEditComplaint;
	private JLabel lblAccount, lblComplaintId, lblComplaintStatus, lblOrderBy;
	private JTextField txtAccount, txtComplaintId;
	private JComboBox cbComplaintStatus, cbOrderBy;
	private String[] complaintStatusOption = {"",ComplaintStatus.PENDING.toString(), ComplaintStatus.CLOSED.toString()};
	private String[] complaintOrderByOption = {SearchSortBy.ACCOUNT_NO.toString(), SearchSortBy.COMPLAINT_NO.toString(), SearchSortBy.COMPLAINT_STATUS.toString() };
	
	private JPanel resultPanel;
	private DefaultTableModel defaultTableModel = new DefaultTableModel() {
		private static final long serialVersionUID = 1L;
		
		public boolean isCellEditable(int row, int column) {
			return false;
		}
	};
	private JTable resultTable = new JTable(defaultTableModel);
	
	public SearchComplaintPanel(BillingApplication billingAppl){
		this.billingAppl = billingAppl;
		this.setOpaque(false);
		
		loadConfiguration();
		resultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		this.setLayout(new BorderLayout());
		this.add(getHeaderPanel(), BorderLayout.NORTH);
		this.add(getSearchPanel(), BorderLayout.CENTER);
		
		resultPanel = new JPanel();
		resultPanel.setOpaque(false);
		this.add(resultPanel, BorderLayout.SOUTH);
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == btnSearch) {
			String accountNo = null;
			String complaintid = null;
			String status = null;
			String selectedSortOrder = cbOrderBy.getSelectedItem().toString();
			
			if (!txtAccount.getText().trim().isEmpty()){
				accountNo = txtAccount.getText().trim();
			}
			if (!txtComplaintId.getText().trim().isEmpty()){
				complaintid = txtComplaintId.getText().trim();
			}
			if (!cbComplaintStatus.getSelectedItem().toString().isEmpty()) {
				status = cbComplaintStatus.getSelectedItem().toString();
			}
			
			HashMap<String, List<Complaint>> resultMap = new HashMap<String, List<Complaint>>();
			try {
				ComplaintController complaintController = new ComplaintController();
				resultMap = complaintController.searchExistingComplaint(accountNo,complaintid, status);
			}
			catch(ControllerException ex) {
				JOptionPane.showMessageDialog(this, ex.getMessage(), properties.getProperty("label.complaint.header.search"), JOptionPane.ERROR_MESSAGE);
				return;
			}
			matchedComplaints = (List<Complaint>)resultMap.get("complaints");
							
			if(matchedComplaints != null && matchedComplaints.size() > 0) {
				Collections.sort(matchedComplaints, new ComplaintSorter(SearchSortBy.valueOf(selectedSortOrder)));
				resultPanel.removeAll();
				resultPanel.add(getResultPanel(matchedComplaints));
				resultPanel.getRootPane().revalidate();
			}
			else {
				resultPanel.removeAll();
				resultPanel.getRootPane().revalidate();
				JOptionPane.showMessageDialog(null, properties.getProperty("error.message.noRecords"), properties.getProperty("label.complaint.header.search"), JOptionPane.INFORMATION_MESSAGE);
			}
			
		}
		else if(e.getSource() == btnViewComplaint || e.getSource() == btnEditComplaint){
			int selectedRow = resultTable.getSelectedRow();
			if(selectedRow > -1){
				Complaint complaint = (Complaint)resultTable.getModel().getValueAt(selectedRow, 5);
				SystemState selectedMode = (e.getSource() == btnViewComplaint) ? SystemState.COMPLAINT_VIEW : SystemState.COMPLAINT_UPDATE;
				billingAppl.displayPage(new ComplaintPanel(billingAppl, selectedMode, complaint, this, null));
			}
			else {
				JOptionPane.showMessageDialog(this, properties.getProperty("error.message.noSelection"), properties.getProperty("label.complaint.header.search"), JOptionPane.INFORMATION_MESSAGE);
			}
		}
	}
	
	private void loadConfiguration() {
		try {
			properties = new Properties();
			FileInputStream in = new FileInputStream(BillingConstants.PROPERTIES_COMPLAINT);
			properties.load(in);
			in.close();
		}
		catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public JPanel getHeaderPanel(){
		JPanel headerPanel = new JPanel();
		headerPanel.setOpaque(false);
		headerPanel.setLayout(new GridLayout(0, 1, 10, 10));
		
		JLabel msgLabel = new JLabel(properties.getProperty("title.searchComplaint"));
		msgLabel.setFont(new Font("Tahoma", Font.BOLD, 18));
		msgLabel.setHorizontalAlignment(SwingConstants.CENTER);
		headerPanel.add(msgLabel);
		
		ImageIcon imgDivider = new ImageIcon("./images/divider.jpg");
		JLabel lblDivider = new JLabel(imgDivider);
		headerPanel.add(lblDivider);
		
		return headerPanel;
	}
	
	public JPanel getSearchPanel() {
		JPanel searchPanel = new JPanel();
		searchPanel.setOpaque(false);
		GridBagLayout layout = new GridBagLayout();
		searchPanel.setLayout(layout);
		
		GridBagConstraints constraints1 = new GridBagConstraints();
		constraints1.insets = new Insets(5, 5, 5, 5);
		constraints1.fill = GridBagConstraints.HORIZONTAL;
		
		GridBagConstraints constraints2 = new GridBagConstraints();
		constraints2.insets = new Insets(5, 5, 5, 50);
		constraints2.fill = GridBagConstraints.HORIZONTAL;
		
		constraints1.gridx = 0;
		constraints1.gridy = 0;
		lblAccount = new JLabel(properties.getProperty("label.complaint.accountNo"));
		lblAccount.setHorizontalAlignment(JLabel.RIGHT);
		searchPanel.add(lblAccount, constraints1);
		
		constraints2.gridx = 1;
		constraints2.gridy = 0;
		txtAccount = new JTextField(20);
		txtAccount.setEditable(true);
		searchPanel.add(txtAccount, constraints2);
		
		constraints1.gridx = 2;
		constraints1.gridy = 0;
		lblComplaintId = new JLabel(properties.getProperty("label.complaint.complaintId"));
		lblComplaintId.setHorizontalAlignment(JLabel.RIGHT);
		searchPanel.add(lblComplaintId, constraints1);
		
		constraints2.gridx = 3;
		constraints2.gridy = 0;
		txtComplaintId= new JTextField(20);
		txtComplaintId.setEditable(true);
		searchPanel.add(txtComplaintId, constraints2);

		constraints1.gridx = 0;
		constraints1.gridy = 1;
		lblComplaintStatus = new JLabel(properties.getProperty("label.complaint.complaintStatus"));
		lblComplaintStatus.setHorizontalAlignment(JLabel.RIGHT);
		searchPanel.add(lblComplaintStatus, constraints1);
		
		constraints2.gridx = 1;
		constraints2.gridy = 1;
		cbComplaintStatus = new JComboBox(complaintStatusOption);
		searchPanel.add(cbComplaintStatus, constraints2);
		
		constraints1.gridx = 2;
		constraints1.gridy = 1;
		lblOrderBy = new JLabel(properties.getProperty("label.complaint.orderBy"));
		lblOrderBy.setHorizontalAlignment(JLabel.RIGHT);
		searchPanel.add(lblOrderBy, constraints1);
		
		constraints2.gridx = 3;
		constraints2.gridy = 1;
		cbOrderBy = new JComboBox(complaintOrderByOption);
		searchPanel.add(cbOrderBy, constraints2);
		
		GridBagConstraints constraints3 = new GridBagConstraints();
		constraints3.insets = new Insets(20, 5, 20, 5);
		constraints3.gridwidth = 4;
		constraints3.gridy = 3;
		constraints3.anchor = GridBagConstraints.CENTER;
		btnSearch = new JButton(properties.getProperty("label.complaint.search"));
		btnSearch.addActionListener(this);
		searchPanel.add(btnSearch, constraints3);
		
		return searchPanel;
	}
		
	public JPanel getResultPanel(List<Complaint> matchedComplaints){
		String[] columnNames = {"No", "Account No.", "Complaint No", "Description", "Status", "ComplaintObject"};
		
		Object[][] data = new Object[matchedComplaints.size()][6];
		for(int n = 0; n < matchedComplaints.size(); n++) {
			Complaint complaint = matchedComplaints.get(n);
			
			data[n][0] = String.valueOf(n+1);
			data[n][1] = complaint.getAccountNo();
			data[n][2] = complaint.getComplaintId();
			data[n][3] = complaint.getComplaintDescription();
			data[n][4] = complaint.getComplaintStatus();
			data[n][5] = complaint;
		}
		
		defaultTableModel.setDataVector(data, columnNames);
		resultTable.setModel(defaultTableModel);
		
		//Set Table Columns widths Begin
		TableColumn col = resultTable.getColumnModel().getColumn(0);
	    col.setPreferredWidth(30);
	    col = resultTable.getColumnModel().getColumn(1);
	    col.setPreferredWidth(150);
	    col = resultTable.getColumnModel().getColumn(2);
	    col.setPreferredWidth(150);
	    col = resultTable.getColumnModel().getColumn(3);
	    col.setPreferredWidth(470);
	    col = resultTable.getColumnModel().getColumn(4);
	    col.setPreferredWidth(100);
	  	//Set Table Columns widths Begin
	    
		resultTable.removeColumn(resultTable.getColumnModel().getColumn(5)); // Not to display to Column.
		resultTable.setPreferredScrollableViewportSize(new Dimension(900,350));
		
		JPanel searchResultPanel = new JPanel();
		searchResultPanel.setOpaque(false);
		searchResultPanel.setLayout(new BorderLayout());
		searchResultPanel.add(new JScrollPane(resultTable), BorderLayout.NORTH);
		
		JPanel actionBtnPanel = new JPanel();
		actionBtnPanel.setOpaque(false);
		
		btnViewComplaint = new JButton(properties.getProperty("label.complaint.viewComplaint"));
		btnViewComplaint.setPreferredSize(new Dimension(200, 25));
		btnViewComplaint.addActionListener(this);
		actionBtnPanel.add(btnViewComplaint);
		
		btnEditComplaint = new JButton(properties.getProperty("label.complaint.editComplaint"));
		btnEditComplaint.setPreferredSize(new Dimension(200, 25));
		btnEditComplaint.addActionListener(this);
		actionBtnPanel.add(btnEditComplaint);
		searchResultPanel.add(actionBtnPanel, BorderLayout.SOUTH);
		
		return searchResultPanel;
	}
}

